/**
 * Copyright 2012-2013 University Of Southern California
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.workflowsim.utils;

import java.util.List;
import org.cloudbus.cloudsim.Log;

/**
 * This class includes most parameters a user can specify in a configuration
 * file
 * 这个类包含了大多数参数，用户可以配置参数文件
 * @author Weiwei Chen
 * @since WorkflowSim Toolkit 1.0
 * @date Apr 9, 2013
 */
public class Parameters {

    
    /*
     * Scheduling Algorithm (Local Scheduling Algorithm)
	 * 调度算法(本地调度算法)
     */

    public enum SchedulingAlgorithm {

        MAXMIN, MINMIN, MCT, DATA, 
        STATIC, FCFS, ROUNDROBIN, INVALID
    }
    
    /**
     * Planning Algorithm (Global Scheduling Algorithm)
     * 规划算法(全局调度算法)
     */
    public enum PlanningAlgorithm{
        INVALID, RANDOM, HEFT, DHEFT
    }
    
    /**
     * File Type
	 * 文件类型
     */
    public enum FileType{
        NONE(0), INPUT(1), OUTPUT(2);
        public final int value;
        private FileType(int fType){
            this.value = fType;
        }
    }
    
    /**
     * File Type
	 * 文件类型
     */
    public enum ClassType{
        STAGE_IN(1), COMPUTE(2), STAGE_OUT(3), CLEAN_UP(4);
        public final int value;
        private ClassType(int cType){
            this.value = cType;
        }
    }
    
    /**
     * The cost model
     * DATACENTER: specify the cost per data center
     * VM: specify the cost per VM
	 * 成本模型 
	 * 数据中心:指定每个数据中心的成本 
	 * VM:指定每个VM（虚拟机）的成本
     */
    public enum CostModel{
        DATACENTER(1), VM(2);
        public final int value;
        private CostModel(int model){
            this.value = model;
        }
    }
    
    /** 
     * Source Host (submit host)
	 *源主机(主机)提交
     */
    public static String SOURCE = "source";
    
    public static final int BASE = 0;
    
    /**
     * Scheduling mode
	 * 调度模型
     */
    private static SchedulingAlgorithm schedulingAlgorithm;
    
    /**
     * Planning mode
	 * 规划模型
     */
    private static PlanningAlgorithm planningAlgorithm;
    
    /**
     * Reducer mode
     */
    private static String reduceMethod;
    /**
     * Number of vms available
	 * 可用的虚拟机数量
     */
    private static int vmNum;
    /**
     * The physical path to DAX file
	 * 综合文件的物理路径
     */
    private static String daxPath;
    
    /**
     * The physical path to DAX files
	 * 综合文件的物理路径
     */
    private static List<String> daxPaths;
    /**
     * The physical path to runtime file In the runtime file, please use format
     * as below ID1 1.0 ID2 2.0 ... This is optional, if you have specified task
     * runtime in DAX then you don't need to specify this file
	 * 运行时文件的物理路径在运行时文件,请使用格式 
	 * 1.0低于ID1 1.0 ID2……这是可选的,如果你有指定的任务 
	 * 运行时在DAX然后你不需要指定文件
     */
    private static String runtimePath;
    /**
     * The physical path to datasize file In the datasize file, please use
     * format as below DATA1 1000 DATA2 2000 ... This is optional, if you have
     * specified datasize in DAX then you don't need to specify this file
	 * datasize datasize文件的物理路径的文件,请使用 
	 * 格式如下DATA1 1000 DATA2 1000…这是可选的,如果你有 
	 * 指定datasize DAX然后你不需要指定文件
     */
    private static String datasizePath;
    /**
     * Version number
	 * 版本号
     */
    private static final String version = "1.1.0";
    /**
     * Note information
	 * 备注信息 
     */
    private static final String note = " supports planning algorithm at Nov 9, 2013";
    /**
     * Overhead parameters
	 * 头参数
     */
    private static OverheadParameters oParams;
    /**
     * Clustering parameters
	 * 聚类参数
     */
    private static ClusteringParameters cParams;
    /**
     * Deadline of a workflow
	 * 一个工作流的最后期限
     */
    private static long deadline;
    
    /**
     * the bandwidth from one vm to one vm
	 * 连接虚拟机之间的带宽
     */
    private static double[][] bandwidths;
    
    
    /**
     * The maximum depth. It is inited manually and used in FailureGenerator
	 * 最大深度。它在FailureGenerator手动初始化和使用
     */
    private static int maxDepth;
    
    /**
     * Invalid String
	 * 无效的字符串
     */
    private static final String INVALID = "Invalid";
    
    /**
     * The scale of runtime. Multiple runtime by this
	 * 运行时的规模。
     */
    private static double runtime_scale = 1.0;
    
    /**
     * The default cost model is based on datacenter, similar to CloudSim
	 * 默认的成本模型是基于数据中心,类似于CloudSim
     */
    private static CostModel costModel = CostModel.DATACENTER;
    
    /**
     * A static function so that you can specify them in any place
     * 一个静态函数,以便您可以指定他们在任何地方
     * @param vm the number of vms虚拟机的数量
     * @param dax the DAX path DAX路径
     * @param runtime optional, the runtime file path 可选的，运行时文件路径
     * @param datasize  optional, the datasize file path 可选的，datasize文件路径
     * @param op overhead parameters 头参数
     * @param cp clustering parameters 聚类参数
     * @param scheduler scheduling mode 调度方式 
     * @param planner planning mode 规划模式
     * @param rMethod  reducer mode 
     * @param dl deadline 工作流的最后期限
     */
    public static void init(
            int vm, String dax, String runtime, String datasize,
            OverheadParameters op, ClusteringParameters cp,
            SchedulingAlgorithm scheduler, PlanningAlgorithm planner, String rMethod,
            long dl) {

        cParams = cp;
        vmNum = vm;
        daxPath = dax;
        runtimePath = runtime;
        datasizePath = datasize;

        oParams = op;
        schedulingAlgorithm = scheduler;
        planningAlgorithm = planner;
        reduceMethod = rMethod;
        deadline = dl;
        maxDepth = 0;
    }
    
    /**
     * A static function so that you can specify them in any place
     * 一个静态函数,以便您可以指定他们在任何地方
     * 
     * @param vm, the number of vms 虚拟机的数量
     * @param dax, the list of DAX paths DAX路径列表
     * @param runtime, optional, the runtime file path 可选的，运行时文件路径
     * @param datasize, optional, the datasize file path 可选的，datasize文件路径
     * @param op, overhead parameters 头参数
     * @param cp, clustering parameters 聚类参数
     * @param scheduler, scheduling mode 调度方式
     * @param planner, planning mode 规划模式
     * @param rMethod , reducer mode reducer模式
     * @param dl, deadline of a workflow 工作流的最后期限
     */
    public static void init(
            int vm, List<String> dax, String runtime, String datasize,
            OverheadParameters op, ClusteringParameters cp,
            SchedulingAlgorithm scheduler, PlanningAlgorithm planner, String rMethod,
            long dl) {

        cParams = cp;
        vmNum = vm;
        daxPaths = dax;
        runtimePath = runtime;
        datasizePath = datasize;

        oParams = op;
        schedulingAlgorithm = scheduler;
        planningAlgorithm = planner;
        reduceMethod = rMethod;
        deadline = dl;
        maxDepth = 0;
    }

    /**
     * Gets the overhead parameters
     *
     * @return the overhead parameters返回头参数
     * @pre $none
     * @post $none
     */
    public static OverheadParameters getOverheadParams() {
        return oParams;
    }

    

    /**
     * Gets the reducer mode
     *
     * @return the reducer
     * @pre $none
     * @post $none
     */
    public static String getReduceMethod() {
        if(reduceMethod!=null){
            return reduceMethod;
        }else{
            return INVALID;
        }
    }

   

    /**
     * Gets the DAX path
     *
     * @return the DAX path
     * @pre $none
     * @post $none
     */
    public static String getDaxPath() {
        return daxPath;
    }

    /**
     * Gets the runtime file path
     *
     * @return the runtime file path
     * @pre $none
     * @post $none
     */
    public static String getRuntimePath() {
        return runtimePath;
    }

    /**
     * Gets the data size path
     *
     * @return the datasize file path
     * @pre $none
     * @post $none
     */
    public static String getDatasizePath() {
        return datasizePath;
    }

    
    /**
     * Gets the vm number
     *
     * @return the vm number
     * @pre $none
     * @post $none
     */
    public static int getVmNum() {
        return vmNum;
    }

    
    /**
     * Gets the cost model
     * 
     * @return costModel
     */
    public static CostModel getCostModel(){
        return costModel;
    }
    
    /**
     * Sets the vm number
     *
     * @param num
     */
    public static void setVmNum(int num) {
        vmNum = num;
    }

    /**
     * Gets the clustering parameters
     *
     * @return the clustering parameters
     */
    public static ClusteringParameters getClusteringParameters() {
        return cParams;
    }

    /**
     * Gets the scheduling method
     *
     * @return the scheduling method
     */
    public static SchedulingAlgorithm getSchedulingAlgorithm() {
        return schedulingAlgorithm;
    }
    
    /**
     * Gets the planning method
     * @return the planning method
     * 
     */
    public static PlanningAlgorithm getPlanningAlgorithm() {
        return planningAlgorithm;
    }
    /**
     * Gets the version
     * @return version
     */
    public static String getVersion(){
        return version;
    }

    public static void printVersion() {
        Log.printLine("WorkflowSim Version: " + version);
        Log.printLine("Change Note: " + note);
    }
    /*
     * Gets the deadline
     */
    public static long getDeadline(){
    	return deadline;
    }
    
    /**
     * Gets the maximum depth
     * @return the maxDepth
     */
    public static int getMaxDepth(){
        return maxDepth;
    }
    
    /**
     * Sets the maximum depth
     * @param depth the maxDepth
     */
    public static void setMaxDepth(int depth){
        maxDepth = depth;
    }
    
    /**
     * Sets the runtime scale
     * @param scale 
     */
    public static void setRuntimeScale(double scale){
        runtime_scale = scale;
    }
    
    /**
     * Sets the cost model
     * @param model
     */
    public static void setCostModel(CostModel model){
        costModel = model;
    }
    
    /**
     * Gets the runtime scale
     * @return 
     */
    public static double getRuntimeScale(){
        return runtime_scale;
    }
    
    /**
     * Gets the dax paths
     * @return 
     */
    public static List<String> getDAXPaths() {
        return daxPaths;
    }
}
